#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
投资分析报告生成器
生成结构化的Markdown报告，包含概率分析、基本面分析和投资建议
"""

import pandas as pd
from datetime import datetime
from typing import List, Dict
import os


class AnalysisReportGenerator:
    """投资分析报告生成器"""
    
    def __init__(self, output_dir: str = "analysis_reports"):
        self.output_dir = output_dir
        self._ensure_output_dir()
    
    def _ensure_output_dir(self):
        """确保输出目录存在"""
        if not os.path.exists(self.output_dir):
            os.makedirs(self.output_dir)
            print(f"[*] 创建报告目录: {self.output_dir}")
    
    def generate_full_report(self, analysis_results: List[Dict], top_n: int = 5) -> str:
        """
        生成完整的投资分析报告
        
        Args:
            analysis_results: 分析结果列表
            top_n: 保留Top N的股票
        
        Returns:
            报告文件路径
        """
        if not analysis_results:
            print("[!] 没有分析结果，无法生成报告")
            return None
        
        # 按预估上涨概率排序，取Top N
        sorted_results = sorted(
            analysis_results, 
            key=lambda x: x['probability']['预估1月上涨概率'], 
            reverse=True
        )
        top_results = sorted_results[:top_n]
        
        # 生成报告内容
        report_content = self._build_report_content(top_results)
        
        # 保存报告
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = os.path.join(self.output_dir, f"投资分析报告_{timestamp}.md")
        
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(report_content)
        
        print(f"\n[✓] 报告已生成: {filename}")
        return filename
    
    def _build_report_content(self, results: List[Dict]) -> str:
        """构建报告内容"""
        content = []
        
        # 报告头部
        content.append(self._generate_header())
        
        # 免责声明
        content.append(self._generate_disclaimer())
        
        # 执行摘要
        content.append(self._generate_executive_summary(results))
        
        # 结构化报表
        content.append(self._generate_probability_table(results))
        
        # 详细分析（每只股票）
        for idx, result in enumerate(results, 1):
            content.append(self._generate_detailed_analysis(result, idx))
        
        # 风险提示
        content.append(self._generate_risk_warning())
        
        return '\n\n'.join(content)
    
    def _generate_header(self) -> str:
        """生成报告头部"""
        now = datetime.now()
        return f"""# 股票投资分析报告

**生成时间**: {now.strftime('%Y年%m月%d日 %H:%M:%S')}  
**报告类型**: 技术面概率分析 + 基本面分析  
**分析周期**: 持有1个月（约20个交易日）

---"""
    
    def _generate_disclaimer(self) -> str:
        """生成免责声明"""
        return """## ⚠️ 免责声明

**本报告仅供教育和参考用途，不构成任何投资建议。**

- 本报告基于历史数据和公开信息进行分析，历史表现不代表未来收益
- 股票投资存在风险，可能导致本金损失
- 投资者应根据自身风险承受能力、投资目标和财务状况做出独立决策
- 建议在投资前咨询专业的投资顾问
- 本报告作者不对投资结果承担任何责任

---"""
    
    def _generate_executive_summary(self, results: List[Dict]) -> str:
        """生成执行摘要"""
        avg_prob = sum(r['probability']['预估1月上涨概率'] for r in results) / len(results)
        
        high_prob_count = sum(1 for r in results if r['probability']['预估1月上涨概率'] > 55)
        
        content = f"""## 📊 执行摘要

本次分析共筛选出 **{len(results)}** 只股票，基于历史数据和当前技术位置进行概率分析：

### 关键发现

- **平均预估上涨概率**: {avg_prob:.2f}%
- **高概率股票（>55%）**: {high_prob_count} 只
- **分析方法**: 基于2-3年历史K线数据，按技术桶位（价格相对MA20/MA60位置）分层统计
- **投资周期**: 建议持有约1个月（20个交易日）

### 概率解读

- **预估1月上涨概率**: 基于当前技术桶位的历史表现
- **全样本上涨概率**: 所有历史交易日买入后20日的上涨概率
- **近1年上涨概率**: 近1年数据的20日上涨概率

---"""
        return content
    
    def _generate_probability_table(self, results: List[Dict]) -> str:
        """生成概率统计表"""
        content = ["""## 📈 结构化概率报表

### 技术面概率统计

| 排名 | 股票代码 | 股票名称 | 当前技术桶位 | 预估1月上涨概率 | 全样本20日上涨概率 | 近1年20日上涨概率 | 20日收益率 均值/中位/标准差 |
|------|----------|----------|--------------|------------------|--------------------|--------------------|----------------------------|"""]
        
        for idx, result in enumerate(results, 1):
            prob = result['probability']
            code = prob['股票代码']
            name = prob['股票名称']
            bucket_desc = prob['技术桶位描述']
            
            pred_prob = prob['预估1月上涨概率']
            all_prob = prob['全样本20日上涨概率']
            recent_prob = prob['近1年20日上涨概率']
            
            mean_ret = prob['20日收益率_均值']
            median_ret = prob['20日收益率_中位数']
            std_ret = prob['20日收益率_标准差']
            
            content.append(
                f"| {idx} | {code} | {name} | {bucket_desc} | "
                f"{pred_prob:.2f}% | {all_prob:.2f}% | {recent_prob:.2f}% | "
                f"{mean_ret:.2f}% / {median_ret:.2f}% / {std_ret:.2f}% |"
            )
        
        content.append("\n### 技术桶位说明\n")
        content.append("- **双上（AboveBoth）**: 价格 > MA20 且 价格 > MA60，表示上升趋势")
        content.append("- **中间（Between）**: 价格在MA20和MA60之间，表示盘整或转折")
        content.append("- **双下（BelowBoth）**: 价格 < MA20 且 价格 < MA60，表示下降趋势")
        
        return '\n'.join(content) + "\n\n---"
    
    def _generate_detailed_analysis(self, result: Dict, rank: int) -> str:
        """生成单只股票的详细分析"""
        prob = result['probability']
        fund = result.get('fundamental', {})
        
        code = prob['股票代码']
        name = prob['股票名称']
        
        content = [f"## {rank}. {code} {name}"]
        
        # 1. 基本面分析
        content.append(self._format_fundamental_analysis(fund))
        
        # 2. 技术面概率分析
        content.append(self._format_probability_analysis(prob))
        
        # 3. 投资建议
        content.append(self._format_investment_advice(prob, fund))
        
        content.append("---")
        
        return '\n\n'.join(content)
    
    def _format_fundamental_analysis(self, fund: Dict) -> str:
        """格式化基本面分析"""
        if not fund or 'basic' not in fund:
            return """### 📋 基本面分析

**数据获取失败或不完整，建议手动查询相关信息**"""
        
        basic = fund.get('基本信息', {})
        financial = fund.get('财务指标', {})
        company = fund.get('公司概况', {})
        valuation = fund.get('估值评估', {})
        
        content = ["""### 📋 基本面分析

#### 公司概况"""]
        
        # 公司信息
        if company.get('主营业务'):
            content.append(f"- **主营业务**: {company.get('主营业务', '暂无')}")
        content.append(f"- **所属行业**: {basic.get('行业', company.get('所属行业', '未知'))}")
        if company.get('上市日期'):
            content.append(f"- **上市日期**: {company.get('上市日期', '未知')}")
        
        # 估值指标
        content.append("\n#### 估值指标")
        content.append(f"- **市盈率PE**: {basic.get('市盈率PE', 0):.2f}")
        content.append(f"- **市净率PB**: {basic.get('市净率PB', 0):.2f}")
        content.append(f"- **总市值**: {basic.get('总市值', 0)/100000000:.2f} 亿元")
        content.append(f"- **估值水平**: {valuation.get('估值水平', '未知')}")
        
        # 财务指标
        content.append("\n#### 财务指标")
        content.append(f"- **ROE（净资产收益率）**: {financial.get('ROE', 0):.2f}%")
        content.append(f"- **净利润增长率**: {financial.get('净利润增长率', 0):.2f}%")
        content.append(f"- **营收增长率**: {financial.get('营收增长率', 0):.2f}%")
        content.append(f"- **净利率**: {financial.get('净利率', 0):.2f}%")
        
        # 投资价值判断
        content.append(f"\n#### 投资价值判断")
        content.append(f"- {valuation.get('投资价值判断', '需进一步研究')}")
        
        return '\n'.join(content)
    
    def _format_probability_analysis(self, prob: Dict) -> str:
        """格式化概率分析"""
        content = ["""### 📊 技术面概率分析

#### 当前技术状态"""]
        
        content.append(f"- **当前价格**: {prob['当前价格']:.2f} 元")
        content.append(f"- **MA20**: {prob['MA20']:.2f} 元")
        content.append(f"- **MA60**: {prob['MA60']:.2f} 元")
        content.append(f"- **技术桶位**: {prob['技术桶位描述']}")
        
        content.append("\n#### 上涨概率统计")
        content.append(f"- **预估1月上涨概率**: {prob['预估1月上涨概率']:.2f}% （基于当前技术桶位）")
        content.append(f"- **全样本20日上涨概率**: {prob['全样本20日上涨概率']:.2f}%")
        content.append(f"- **近1年20日上涨概率**: {prob['近1年20日上涨概率']:.2f}%")
        
        content.append("\n#### 收益率统计（20个交易日）")
        content.append(f"- **平均收益率**: {prob['20日收益率_均值']:.2f}%")
        content.append(f"- **中位数收益率**: {prob['20日收益率_中位数']:.2f}%")
        content.append(f"- **收益率标准差**: {prob['20日收益率_标准差']:.2f}%")
        
        # 技术桶位对比
        if '桶位统计' in prob:
            content.append("\n#### 不同技术桶位历史表现对比")
            bucket_stats = prob['桶位统计']
            
            for bucket_name, stats in bucket_stats.items():
                if stats['样本量'] > 0:
                    bucket_desc = {
                        'AboveBoth': '双上',
                        'Between': '中间',
                        'BelowBoth': '双下'
                    }.get(bucket_name, bucket_name)
                    
                    content.append(
                        f"- **{bucket_desc}**: 上涨概率 {stats['上涨概率']:.2f}%, "
                        f"平均收益 {stats['平均收益率']:.2f}%, "
                        f"样本量 {stats['样本量']}"
                    )
        
        return '\n'.join(content)
    
    def _format_investment_advice(self, prob: Dict, fund: Dict) -> str:
        """格式化投资建议"""
        content = ["""### 💡 投资建议框架

**注意：以下建议仅供参考，不构成投资建议**"""]
        
        # 风险收益评估
        pred_prob = prob['预估1月上涨概率']
        mean_ret = prob['20日收益率_均值']
        std_ret = prob['20日收益率_标准差']
        
        content.append("\n#### 风险收益评估")
        
        if pred_prob > 60:
            risk_level = "中等"
            advice = "基于历史数据，当前技术位置具备较高的上涨概率"
        elif pred_prob > 50:
            risk_level = "中等偏高"
            advice = "上涨概率略高于50%，但仍存在较大不确定性"
        else:
            risk_level = "较高"
            advice = "上涨概率低于50%，建议谨慎对待"
        
        content.append(f"- **预期收益**: 平均 {mean_ret:.2f}%，中位数 {prob['20日收益率_中位数']:.2f}%")
        content.append(f"- **风险水平**: {risk_level} （标准差 {std_ret:.2f}%）")
        content.append(f"- **概率解读**: {advice}")
        
        # 仓位管理建议
        content.append("\n#### 仓位管理建议")
        
        if pred_prob > 60 and std_ret < 15:
            position = "10-15%"
            reason = "概率较高且波动适中"
        elif pred_prob > 55:
            position = "5-10%"
            reason = "概率适中，控制仓位"
        else:
            position = "3-5%"
            reason = "概率不高，小仓位试探"
        
        content.append(f"- **建议仓位**: {position} （{reason}）")
        content.append("- **分批建仓**: 建议分2-3次买入，降低择时风险")
        
        # 止损止盈策略
        content.append("\n#### 止损止盈策略")
        content.append(f"- **止损位**: 买入价的 -8% 至 -10%")
        content.append(f"- **止盈位**: 根据个股情况，建议 +12% 至 +15%")
        content.append(f"- **时间止损**: 持有超过1.5个月（30个交易日）未达预期，考虑离场")
        
        # 持有期限
        content.append("\n#### 建议持有期限")
        content.append("- **目标周期**: 1个月（约20个交易日）")
        content.append("- **动态调整**: 根据市场环境和个股表现灵活调整")
        
        # 风险控制要点
        content.append("\n#### 风险控制要点")
        content.append("1. **严格执行止损**: 跌破止损位必须离场，避免情绪化决策")
        content.append("2. **关注大盘**: 大盘系统性风险时应降低仓位")
        content.append("3. **分散投资**: 不要将资金集中在单只股票")
        content.append("4. **定期复盘**: 每周复盘持仓，及时调整策略")
        content.append(f"5. **监控波动**: 该股票标准差为 {std_ret:.2f}%，注意波动风险")
        
        return '\n'.join(content)
    
    def _generate_risk_warning(self) -> str:
        """生成风险提示"""
        return """## ⚠️ 重要风险提示

### 数据局限性

1. **历史数据不代表未来**: 概率统计基于历史数据，市场环境变化可能导致未来表现不同
2. **样本偏差**: 不同技术桶位的样本量可能不均衡，影响统计有效性
3. **数据时效性**: 基本面数据可能存在滞后，建议查阅最新公告

### 投资风险

1. **市场风险**: 整体市场下跌时，个股难以独善其身
2. **流动性风险**: 部分股票可能存在流动性不足的问题
3. **政策风险**: 行业政策变化可能影响股价
4. **黑天鹅事件**: 突发事件可能导致股价剧烈波动

### 投资纪律

1. **不要满仓**: 始终保持资金的灵活性
2. **不要追涨杀跌**: 理性决策，避免情绪化操作
3. **不要盲目相信**: 任何分析都有局限性，需要独立思考
4. **不要借钱炒股**: 使用闲置资金，承受得起损失

---

**最后提醒**: 股市有风险，投资需谨慎！请在充分了解风险的前提下，根据自身情况做出理性决策。

---

**报告生成工具**: findGuPiao 股票分析系统  
**技术支持**: 基于东方财富API数据  
**更新频率**: 建议每周更新一次分析"""
    
    def print_summary(self, results: List[Dict]):
        """在控制台打印摘要"""
        print("\n" + "="*100)
        print(" 投资分析摘要 ".center(100, "="))
        print("="*100)
        
        for idx, result in enumerate(results, 1):
            prob = result['probability']
            fund = result.get('fundamental', {})
            
            print(f"\n【{idx}】{prob['股票代码']} {prob['股票名称']}")
            print(f"  技术桶位: {prob['技术桶位描述']}")
            print(f"  预估1月上涨概率: {prob['预估1月上涨概率']:.2f}%")
            print(f"  全样本上涨概率: {prob['全样本20日上涨概率']:.2f}%")
            print(f"  平均收益率: {prob['20日收益率_均值']:.2f}% (标准差: {prob['20日收益率_标准差']:.2f}%)")
            
            if fund and '基本信息' in fund:
                basic = fund['基本信息']
                print(f"  估值: PE={basic.get('市盈率PE', 0):.2f}, PB={basic.get('市净率PB', 0):.2f}")
        
        print("\n" + "="*100 + "\n")


if __name__ == '__main__':
    # 测试报告生成
    test_results = [
        {
            'probability': {
                '股票代码': '600895',
                '股票名称': '张江高科',
                '当前价格': 15.50,
                'MA20': 15.20,
                'MA60': 14.80,
                '技术桶位': 'AboveBoth',
                '技术桶位描述': '双上（价格>MA20>MA60）',
                '预估1月上涨概率': 55.5,
                '全样本20日上涨概率': 48.5,
                '近1年20日上涨概率': 52.3,
                '20日收益率_均值': 2.5,
                '20日收益率_中位数': 1.2,
                '20日收益率_标准差': 12.5,
                '桶位统计': {}
            },
            'fundamental': {}
        }
    ]
    
    generator = AnalysisReportGenerator()
    generator.print_summary(test_results)
